//
//  RLLocationHelper.m
//
//  Created by jun on 14-3-18.
//  Copyright (c) 2014年 . All rights reserved.
//

#import "RLMapHelper.h"
#import <MapKit/MapKit.h>

@implementation RLMapHelper

#pragma mark - 地球坐标(原始GPS坐标)和火星坐标（高德/Google中国）互转

const double g_pi = M_PI;
//3.14159265358979324;
const double g_a = 6378245.0;
const double g_ee = 0.00669342162296594323;


/// 火星坐标转地球坐标
+ (CLLocationCoordinate2D)gcj02ToWgs84:(CLLocationCoordinate2D)gcj02Coor
{
    double lon = gcj02Coor.longitude;
    double lat = gcj02Coor.latitude;
    
    CLLocationCoordinate2D coor = [self wgs84ToGcj02:gcj02Coor];
    
    double lontitude = lon - (coor.longitude - lon);
    double latitude = lat - (coor.latitude - lat);
    
    return CLLocationCoordinate2DMake(latitude, lontitude);
    
}

/// 地球坐标系(真实GPS坐标)转火星坐标（高德坐标）
+ (CLLocationCoordinate2D)wgs84ToGcj02:(CLLocationCoordinate2D)wgs84Coor
{
    CLLocationCoordinate2D gcj02Coor;
    
    double dLat = transformLat(wgs84Coor.longitude-105.0, wgs84Coor.latitude-35.0);
    
    double dLon = transformLon(wgs84Coor.longitude-105.0, wgs84Coor.latitude-35.0);
    
    double radLat = wgs84Coor.latitude/180.0*g_pi;
    
    double magic = sin(radLat);
    
    magic = 1-g_ee*magic*magic;
    
    double sqrtMagic = sqrt(magic);
    
    dLat = (dLat * 180.0) / ((g_a * (1 - g_ee)) / (magic * sqrtMagic) * g_pi);
    
    dLon = (dLon * 180.0) / (g_a / sqrtMagic * cos(radLat) * g_pi);
    
    gcj02Coor = CLLocationCoordinate2DMake(wgs84Coor.latitude+dLat, wgs84Coor.longitude+dLon);
    
    return gcj02Coor;
}

double transformLat(double x, double y)
{
    
    double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs((int)x));
    
    ret += (20.0 * sin(6.0 * x * g_pi) + 20.0 * sin(2.0 * x * g_pi)) * 2.0 / 3.0;
    
    ret += (20.0 * sin(y * g_pi) + 40.0 * sin(y / 3.0 * g_pi)) * 2.0 / 3.0;
    
    ret += (160.0 * sin(y / 12.0 * g_pi) + 320 * sin(y * g_pi / 30.0)) * 2.0 / 3.0;
    
    return ret;
    
}


double transformLon(double x, double y)
{
    
    double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs((int)x));
    
    ret += (20.0 * sin(6.0 * x * g_pi) + 20.0 * sin(2.0 * x * g_pi)) * 2.0 / 3.0;
    
    ret += (20.0 * sin(x * g_pi) + 40.0 * sin(x / 3.0 * g_pi)) * 2.0 / 3.0;
    
    ret += (150.0 * sin(x / 12.0 * g_pi) + 300.0 * sin(x / 30.0 * g_pi)) * 2.0 / 3.0;
    
    return ret;
    
}

#pragma mark - 坐标抽稀算法

////使用抽稀算法(垂距限值法)将路线的点稀释
////参数oldPointArray放NSValue，NSValue放MKMapPoint
//+ (NSMutableArray*)vacuateMapRoutePoint:(NSMutableArray*)oldPointArray
//{
//    if (!oldPointArray || oldPointArray.count < 4) return oldPointArray;
//    
//    /*
//     向东南方向移动1米的两个MKMapPoint
//     mp.x1=221004667.685729, mp.y1=101716275.688126
//     mp.x2=221004675.142269, mp.y2=101716284.436433
//     两个MKMapPoint点直接的距离c为：
//     c^2 = |y2-y1|^2 + |x2-x1|^2
//     c = 开平方(|y2-y1|^2 + |x2-x1|^2)
//     c = 11.95112630675452
//     所以每隔1米，MKMapPoint两个点的距离约为11.95112630675452
//     */
//    
//    double threshold = 11.951126 * 100; //阀值，决定了抽稀程度，越大越稀，这里为100米。
//    NSMutableArray *delIndexArray = [NSMutableArray array];
//    NSInteger beginIndex = 0, midIndex = beginIndex+1, endIndex = midIndex+1;
//    
//    while (endIndex < oldPointArray.count-1) {
//        
//        NSValue *val1 = [oldPointArray objectAtIndex:beginIndex];
//        MKMapPoint point1;
//        [val1 getValue:&point1];
//        
//        NSValue *val2 = [oldPointArray objectAtIndex:midIndex];
//        MKMapPoint point2;
//        [val2 getValue:&point2];
//        
//        NSValue *val3 = [oldPointArray objectAtIndex:endIndex];
//        MKMapPoint point3;
//        [val3 getValue:&point3];
//        
//        //
////        CLLocationCoordinate2D coor1 = [val1 MKCoordinateValue];
////        CLLocationCoordinate2D coor2 = [val2 MKCoordinateValue];
////        CLLocationCoordinate2D coor3 = [val3 MKCoordinateValue];
////        
////        //
////        CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:coor1.latitude longitude:coor1.longitude];
////        CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:coor2.latitude longitude:coor2.longitude];
////        CLLocation *loc3 = [[CLLocation alloc] initWithLatitude:coor3.latitude longitude:coor3.longitude];
////        
////        //
////        double distance21 = [loc2 distanceFromLocation:loc1];
////        double distance23 = [loc2 distanceFromLocation:loc3];
//        
//        //勾股定义求两坐标点连成的直线长度
//        // A(x1,y1), B(x2,y2)
//        // lineLen^2 = |x1-x2|^2 + |y1-y2|^2
//        // lineLen = sqrt( powf(fabs(x1-x2),2) + powf(fabs(y1-y2),2) );
//        double lineLen = sqrt( powf(fabs(point1.x-point3.x),2) + powf(fabs(point1.y-point3.y),2) );
//        NSLog(@">>> threshold=%f, lineLen=%f", threshold, lineLen);
//        
//        if (lineLen < threshold) {
//
////            [newPointArray removeObjectAtIndex:midIndex];
//            [delIndexArray addObject:[NSNumber numberWithInteger:midIndex]];
//            
//            midIndex += 1;
//            endIndex = midIndex + 1;
//        }
//        else {
//            beginIndex = midIndex;
//            midIndex += 1;
//            endIndex = midIndex + 1;
//        }
//    }
//    
//    
//    if (delIndexArray.count > 0) {
//        NSMutableArray *newPointArray = [NSMutableArray array];
//        for (NSInteger i=0; i<oldPointArray.count; i++) {
//            BOOL isExistus = NO;
//            for (NSNumber *num in delIndexArray) {
//                NSInteger delIndex = [num integerValue];
//                if (i == delIndex) {
//                    isExistus = YES;
//                    break;
//                }
//            }
//            
//            if (!isExistus) {
//                [newPointArray addObject:[oldPointArray objectAtIndex:i]];
//            }
//        }
//        //
//        return newPointArray;
//    }
//    
//    return oldPointArray;
//}

//使用抽稀算法(垂距限值法)将路线的点稀释
//参数oldPointArray放NSValue，NSValue放CLLocationCoordinate2D
+ (NSArray*)vacuateMapRoutePoint:(NSArray*)oldPointArray
{
    if (!oldPointArray || oldPointArray.count < 3) return oldPointArray;
    
    /*
     向东南方向移动1米的两个MKMapPoint
     mp.x1=221004667.685729, mp.y1=101716275.688126
     mp.x2=221004675.142269, mp.y2=101716284.436433
     两个MKMapPoint点直接的距离c为：
     c^2 = |y2-y1|^2 + |x2-x1|^2
     c = 开平方(|y2-y1|^2 + |x2-x1|^2)
     c = 11.95112630675452
     所以每隔1米，MKMapPoint两个点的距离约为11.95112630675452
     */
    
    double threshold = 11.95112630675452 * 6; //阀值（垂距），决定了抽稀程度，越大越稀，这里垂距为6米。
    NSMutableArray *delIndexArray = [NSMutableArray array];
    NSInteger beginIndex = 0, midIndex = beginIndex+1, endIndex = midIndex+1;
    
    while (endIndex < oldPointArray.count-1) {
        
        NSValue *val1 = [oldPointArray objectAtIndex:beginIndex];
        MKMapPoint point1 = MKMapPointForCoordinate(val1.MKCoordinateValue);

        NSValue *val2 = [oldPointArray objectAtIndex:midIndex];
        MKMapPoint point2 = MKMapPointForCoordinate(val2.MKCoordinateValue);
        
        NSValue *val3 = [oldPointArray objectAtIndex:endIndex];
        MKMapPoint point3 = MKMapPointForCoordinate(val3.MKCoordinateValue);
 
//        double lineLen = pointToPointLength(point1.x, point1.y, point3.x, point3.y);
        //点到直线的垂直距离
        double p2LineLen = pointToLineLength(point1.x, point1.y, point3.x, point3.y, point2.x, point2.y);
//        NSLog(@">>> threshold=%f, lineLen=%f, p2LineLen=%f", threshold, lineLen, p2LineLen);
//        double p1p2Length = pointToPointLength(point1.x, point1.y, point2.x, point2.y);
        
//        || p1p2Length < threshold
        if (p2LineLen < threshold) { //点到直线的垂直距离小于阀值则删除这个点;
            
            //            [newPointArray removeObjectAtIndex:midIndex];
            [delIndexArray addObject:[NSNumber numberWithInteger:midIndex]];
            
            midIndex += 1;
            endIndex = midIndex + 1;
        }
        else {
            beginIndex = midIndex;
            midIndex += 1;
            endIndex = midIndex + 1;
        }
    }
    
    
    if (delIndexArray.count > 0) {
        NSMutableArray *newPointArray = [NSMutableArray array];
        for (NSInteger i=0; i<oldPointArray.count; i++) {
            BOOL isExistus = NO;
            for (NSNumber *num in delIndexArray) {
                NSInteger delIndex = [num integerValue];
                if (i == delIndex) {
                    isExistus = YES;
                    break;
                }
            }
            
            if (!isExistus) {
                [newPointArray addObject:[oldPointArray objectAtIndex:i]];
            }
        }
        //
        return newPointArray;
    }
    
    return oldPointArray;
}


/// 两点之间(x1,y1)到(x2,y2)的距离：
double pointToPointLength(double x1, double y1, double x2, double y2) {
    return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
}

/// 点(x3,y3)到线(x1,y1)-(x2,y2)之间的距离：
double pointToLineLength(double x1, double y1, double x2, double y2, double x3, double y3) {
    double A, B, C, D;
    A = y1 - y2;
    B = x2 - x1;
    C = x1 * y2 - x2 * y1;
    D = fabsl(A * x3 + B * y3 + C) / sqrt(A * A + B * B);
    return D;
}

@end

